/*
    Copyright 2009 Semantic Discovery, Inc. (www.semanticdiscovery.com)

    This file is part of the Semantic Discovery Toolkit.

    The Semantic Discovery Toolkit is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    The Semantic Discovery Toolkit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with The Semantic Discovery Toolkit.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;

namespace SemanticDiscovery.Util {

  /**
   * NUnit Tests for the GeneralUtil class.
   * <p>
   * @author Spence Koehler
   */
  [TestFixture]
  public class TestGeneralUtil {

    [TestCase]
    public void TestCombine() {
      // combineInput, expectedOutput
      string[][][] combineData = new string[][][] {
        new string[][] { 
          // ((a b) (c d)) ==> ((a c) (a d) (b c) (b d))
          new string[] {"a,b", "c,d"}, 
          new string[] {"a,c a,d b,c b,d"}
        },
        new string[][] { 
          // ((a b c) (d e f)) ==> ((a d) (a e) (a f) (b d) (b e) (b f) (c d) (c e) (c f))
          new string[] {"a,b,c", "d,e,f"}, 
          new string[] {"a,d a,e a,f b,d b,e b,f c,d c,e c,f"},
        },
        new string[][] { 
          // ((a b) (c d) (e f)) ==> ((a c e) (a c f) (a d e) (a d f) (b c e) (b c f) (b d e) (b d f))
          new string[] {"a,b", "c,d", "e,f"}, 
          new string[] {"a,c,e a,c,f a,d,e a,d,f b,c,e b,c,f b,d,e b,d,f"},
        },
        new string[][] { 
          // ((a) (b) (c)) ==> ((a b c))
          new string[] {"a", "b", "c"}, 
          new string[] {"a,b,c"},
        },
        new string[][] { 
          // ((a)) ==> ((a))
          new string[] {"a"}, 
          new string[] {"a"},
        },
        new string[][] { 
          // ((a b c d)) ==> ((a) (b) (c) (d))
          new string[] {"a,b,c,d"}, 
          new string[] {"a b c d"}
        }
      };

      for (int i = 0; i < combineData.Length; ++i) {
        IList<ICollection<string>> input = strings2List(combineData[i][0]);
        string expected = combineData[i][1][0];

        IList<ICollection<string>> combined = GeneralUtil.Combine(input);
        string output = asString(combined);

        Assert.AreEqual(expected, output);
      }
    }

    /** Auxiliary for testCombine. */
    private IList<ICollection<string>> strings2List(string[] strings) {
      IList<ICollection<string>> result = new List<ICollection<string>>();
      for (int i = 0; i < strings.Length; ++i) {
        string[] subList = strings[i].Split(new char[] {','});
        result.Add(subList.ToList());
      }
      return result;
    }

    /** Auxiliary for testCombine. */
    private string asString(IList<ICollection<string>> collections) {
      StringBuilder result = new StringBuilder();

      bool firstColl = true;
      foreach(ICollection<string> curList in collections) {
        if (firstColl)
          firstColl = false;
        else
          result.Append(' ');

        bool firstItem = true;
        foreach(string curObject in curList) {
          if(firstItem)
            firstItem = false;
          else
            result.Append(',');

          result.Append(curObject.ToString());
        }
      }

      return result.ToString();
    }

  }

}
